#include "Facility.h"
#ifndef HEAD_H
#include "../head.h"
#endif
Facility::Facility(FacilityDefine *define, FacilityDirection f_dir, Coordinate coordinate,Cargo_Manager * cargo_manager)
    :define(define),
    cargo_manager(cargo_manager),
    object_qt(null),
    time_record(0),
    coordinate(coordinate),
    my_x(coordinate.x*BOX_LENTH),
    my_y(coordinate.y*BOX_LENTH),
    facility_direction(f_dir),
    width(define->width),
    height(define->height),
    abs_enters(define->relative_enters),
    abs_exits(define->relative_exits),
    next_facility(define->exits_num,{null,-1}),
    pre_facility(define->enters_num,{null,-1}),
    incargos(define->enters_num,null),
    storecargos(define->enters_num,null),
    outcargos(define->exits_num,null)
{

    Coordinate leftup_co = coordinate;
    // 根据 方向 和 坐标 算出 设施左上角的坐标 和 设施的长宽
    switch(facility_direction){
    case FacilityDirection::Facility_UP:
        break;
    case FacilityDirection::Facility_RIGHT:
        leftup_co.x += define->height - 1;
        std::swap(width,height);
        break;
    case FacilityDirection::Facility_DOWN:
        leftup_co.x += define->height - 1;
        leftup_co.y += define->width - 1;
        break;
    case FacilityDirection::Facility_LEFT:
        leftup_co.y += define->width - 1;
        std::swap(width,height);
        break;
    default:
        std::cerr << "FacilityDirection Failed";
        break;
    }
    // 根据 方向 和 左上坐标 算出 绝对位置
    for(int i = 0; i < define->enters_num; ++i){
        abs_enters[i].turn90ClockWise(f_dir);
        abs_enters[i].moveBy(leftup_co);
    }
    for(int i = 0; i < define->exits_num; ++i){
        abs_exits[i].turn90ClockWise(f_dir);
        abs_exits[i].moveBy(leftup_co);
    }

}

void Facility::linkObject(Object_Qt * obj){
    this->object_qt = obj;
}

Object_Qt * Facility::removeObject(){
    Object_Qt * obj = this->object_qt;
    this->object_qt = null;
    return obj;
}

void Facility::processCargo(){
    this->sendCargo();
    // this->takeCargo();
    bool flag = inEmpty() || !outEmpty();
    if(flag){
        return ; // 堵塞或没有材料
    }
    // else
    this->duringProcess();
    if(++time_record >= define->interval){
        time_record = 0;
        this->finishProcess();
    }
}

void Facility::finishProcess(){

    for(auto c:outcargos){
        if(c != null){
            if(c->object_qt)
            {
                // // qDebug() << c->object_qt->pos();
                // c->object_qt->hide();
            }
            // // qDebug() << c->define->hash_id;
        }
    }
}

bool Facility::isValid(){
    return true;
}

void Facility::duringProcess(){}

void Facility::sendCargo(){
    for(int i = 0; i < this->next_facility.size(); ++i) //自家的 i
    {
        Facility * &ne_f = this->next_facility[i].first;
        int idx = this->next_facility[i].second; // 对面的的idx
        if(!ne_f || idx < 0){continue;}
        if(ne_f->incargos[idx] == null){
            // qDebug()<<"send";
            ne_f->incargos[idx] = this->outcargos[i];
            this->outcargos[i] = null;
            Cargo * c = ne_f->incargos[idx];
            // if(c)
            // {
            //     c->obj_moveTo(my_x,my_y,ne_f->abs_enters[idx].direction);
            //     c->object_qt->show();
            // }
        }
    }
}

void Facility::takeCargo(){

    for(int i = 0; i < this->pre_facility.size(); ++i)//自家的 i
    {

        Facility *& pre_f = this->pre_facility[i].first;
        int idx = this->pre_facility[i].second; // 对面的idx
        if(!pre_f || idx < 0){continue;}
        if(this->incargos[i] == null){
            // qDebug()<<"take";
            this->incargos[i] = pre_f->outcargos[idx];
            pre_f->outcargos[idx] = null;
            Cargo * c = this->incargos[i];
            // if(c){
            //     c->obj_moveTo(my_x,my_y,this->abs_enters[i].direction);
            //     c->object_qt->show();
            // }
        }

    }

}

bool Facility::inEmpty(){
    for(int i = 0; i < incargos.size(); ++i){
        if(incargos[i] == null) return true;
    }
    return false;
}
/// @brief 所有out为空则为真
bool Facility::outEmpty(){
    for(int i = 0; i < outcargos.size(); ++i){
        if(outcargos[i]) return false;
    }
    return true;
}

/// 1. 释放 货物内存
/// 2. 切断 设施连接
/// 3. 图片在Manager中清除
Facility::~Facility(){
    /// 1. 释放 货物内存
    for(int i = 0; i < incargos.size(); ++i){
        if(incargos[i]){delete incargos[i];}
        incargos[i] = null;
    }
    for(int i = 0; i < outcargos.size(); ++i){
        if(outcargos[i]){delete outcargos[i];}
        outcargos[i] = null;
    }
    /// 2. 切断连接
    for(int i = 0 ; i < next_facility.size(); ++i){
        Facility * f = next_facility[i].first;
        if(!f){continue;}
        f->pre_facility[next_facility[i].second]= {null,-1};
    }
    for(int i = 0 ; i < pre_facility.size(); ++i){
        Facility * f = pre_facility[i].first;
        if(!f){continue;}
        f->next_facility[pre_facility[i].second]= {null,-1};
    }
}



